import geo2
import trinity
from actorfactory.PropertyApplier import ApplyPropertiesToObject
__RegisteredFactorys = {}
__SelfCleaningFactories = {}

class BaseActorFactory(object):

    def __init__(self):
        return 



    def Register(self, factoryList):
        return 



    def CreateObject(self, template, vPos, vForward, vNorm, properties = {}):
        return 



    def AddToScene(self, scene, obj, template):
        return False



    def IsSelfCleaning(self):
        return False



    def HandleScale(self, template, transform):
        if ((template.configData != None) and ('scale' in template.configData)):
            transform._11 *= template.configData['scale']
            transform._22 *= template.configData['scale']
            transform._33 *= template.configData['scale']
        if ((template.configData != None) and ('scalexyz' in template.configData)):
            transform._11 *= template.configData['scalexyz'][0]
            transform._22 *= template.configData['scalexyz'][1]
            transform._33 *= template.configData['scalexyz'][2]
        return transform



    def HandlePosition(self, template, transform, vPos):
        transform._41 = vPos.x
        transform._42 = vPos.y
        transform._43 = vPos.z
        return transform



    def HandleAlignment(self, template, transform, vNorm):
        import app.Common.Utility as Utility
        if template.alignGround:
            qRot = geo2.QuaternionRotationArc((0.0, 1.0, 0.0), vNorm)
            mRot = geo2.MatrixRotationQuaternion(qRot)
            mTransform = Utility.TriToGeo(transform)
            mTransform = geo2.MatrixMultiply(mTransform, mRot)
            transform = Utility.GeoToTri(mTransform)
        return transform



    def HandleAlignmentForward(self, template, transform, vForward):
        import app.Common.Utility as Utility
        vFwd = (vForward * 1.0)
        vFwd.y = 0.0
        qRot = geo2.QuaternionRotationArc(vFwd, (0.0, 0.0, 1.0))
        mRot = geo2.MatrixRotationQuaternion(qRot)
        mTransform = Utility.TriToGeo(transform)
        mTransform = geo2.MatrixMultiply(mTransform, mRot)
        transform = Utility.GeoToTri(mTransform)
        return transform



    def HandleProperties(self, object, properties):
        ApplyPropertiesToObject(properties, object)




def RegisterFactory(factory):
    factory.Register(__RegisteredFactorys)
    if factory.IsSelfCleaning():
        factory.Register(__SelfCleaningFactories)



def CreateObject(template, vPos, vForward, vNorm, properties = {}):
    if (template == None):
        print 'ERROR: Actorfactory can not create object from None Template'
        return 
    classType = template.GetClassType()
    if (classType in __RegisteredFactorys):
        factory = __RegisteredFactorys[classType]
        return factory.CreateObject(template, vPos, vForward, vNorm, properties)



def AddToScene(scene, obj, template):
    classType = template.GetClassType()
    if (classType in __RegisteredFactorys):
        factory = __RegisteredFactorys[classType]
        factory.AddToScene(scene, obj, template)
        return True
    else:
        return False



def RemoveFromScene(scene, obj, template):
    classType = template.GetClassType()
    if (classType in __SelfCleaningFactories):
        factory = __SelfCleaningFactories[classType]
        factory.RemoveFromScene(scene, obj, template)
        return True
    else:
        return False



def GetFactoryForTemplate(template):
    classType = template.GetClassType()
    factory = None
    if (classType in __RegisteredFactorys):
        factory = __RegisteredFactorys[classType]
    return factory



